package com.example.rabbit.listener;


import com.example.rabbit.entity.User;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

import org.springframework.amqp.core.Message;


/**
 * 消息 接收者
 */
@Component
public class AckReceiver {
    // 若配置了ack队列 的 监听消费，手动ack，需要spring.rabbitmq.listener.simple.acknowledge-mode=manual
    @RabbitListener(queues = "ack_queue")
    @RabbitHandler
    public void getAck_queue_Msg(@Payload String mail, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel, Message message) throws IOException {
        System.out.println("消费者1从ack_queue队列取出消息："+mail.toString());
        System.out.println(deliveryTag);
        //System.out.println(message);
        System.out.println("--------------------------");
        try{
            //成功回执
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            //重新放入队列
            //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            //抛弃此条消息
            // channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }catch (Exception e){
           e.printStackTrace();
            if (message.getMessageProperties().getRedelivered()){
                System.out.println("消息已重复处理失败,拒绝再次接收... ，将直接投入死信队列");
                // 拒绝消息  requeue：true该条消息重新返回MQ false直接丢弃
                channel.basicReject(deliveryTag, false);
            }else {
                System.out.println("消息即将再次返回队列处理...  ，如果再一次无法正常basicAck，那么就会执行basicReject");
                /*
                 * deliveryTag：该消息的index
                 * multiple: ture确认本条消息以及之前没有确认的消息(批量)，false仅确认本条消息
                 * requeue: true该条消息重新返回MQ queue，MQ broker将会重新发送该条消息
                 */
                channel.basicNack(deliveryTag,false,true);
            }
        }finally {
            try {
                channel.close();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }

    }
}
